<?php

namespace addons\shopro\service;

use addons\shopro\service\Wallet as WalletService;
use app\admin\model\Individuality;
use app\admin\model\PaymentMoneyLog;
use app\admin\model\RechargeCorrectLog;
use app\admin\model\shopro\commission\Agent;
use app\admin\model\shopro\commission\Level;
use app\admin\model\shopro\Pclog;
use app\admin\model\shopro\user\User;
use think\exception\HttpResponseException;
use app\admin\model\shopro\user\User as UserModel;
use app\admin\model\shopro\user\WalletLog;
use addons\shopro\library\Operator;
use app\common\model\MoneyLog;
use app\common\model\ScoreLog;

class Wallet
{
    /**
     * @name 变更会员资金
     * @param  int|object   $user       会员对象或会员ID
     * @param  string       $type       变更类型:money=余额,commission=佣金,score=积分
     * @param  float|string        $amount     变更数量
     * @param  array        $ext        扩展字段
     * @param  string       $memo       备注
     * @return boolean
     */
    public static function change($user, $type, $amount, $event, $ext = [], $memo = '',$flow_id=0)
    {
        // 判断用户
        if (is_numeric($user)) {
            $user = UserModel::getById($user);
        }
        /* if (!$user) {
             error_stop('未找到用户');
         }*/
        // 判断金额
        /*if ($amount == 0) {
            error_stop('请输入正确的金额');
        }*/
        if (!in_array($type, ['money', 'score', 'commission'])) {
            error_stop('参数错误');
        }

        $before = $user->$type;
        $after = bcadd((string)$user->$type, (string)$amount, 2);
        // 只有后台扣除用户余额、扣除用户积分、佣金退回，钱包才可以是负值

        /* if ($after < 0 && !in_array($event, ['admin_recharge', 'reward_back'])) {
             $walletTypeText = WalletLog::TYPE_MAP[$type];
             error_stop("可用{$walletTypeText}不足");
         }*/
        try {
            // 更新会员余额信息
            $user->setInc($type, $amount);
            // 获取操作人
            $oper = Operator::get();
            // 写入日志
            $log=new WalletLog();
            $walletLog = WalletLog::create([
                'user_id' => $user->id,
                'amount' => $amount,
                'type' => $type,
                'before' => $before,
                'after' => $after,
                'event' => $event,
                'memo' => $memo,
                'ext' => $ext,
                'oper_type' => $oper['type'],
                'oper_id' => $oper['id'],
                'order_id' => $ext["order_id"]??0,
                'flow_id' =>$flow_id,//流向用户id
            ]);
            if($event=="admin_recharge"){
                //后台充值余额
                //平台记录
                Pclog::create([
                    "order_id"=>$walletLog["id"],
                    "type"=>4,
                    "money"=>$amount,
                    "pv_price"=>$amount,
                    "ext"=>$ext,
                    "user_id"=>$user->id,
                    "createtime"=>time(),
                ]);
            }
            // 钱包和积分记录存到 fastadmin 钱包积分记录表
            if (in_array($type, ['money', 'score'])) {
                $eventMap = (new WalletLog)->getEventMap();
                $memo = $memo ?$memo: ($eventMap[$type][$event] ?? '');
                if ($type === 'money') {
                    MoneyLog::create(['user_id' => $user->id, 'money' => $amount, 'before' => $before, 'after' => $after, 'memo' => $memo]);
                } else if ($type === 'score') {
                    ScoreLog::create(['user_id' => $user->id, 'score' => $amount, 'before' => $before, 'after' => $after, 'memo' => $memo]);
                }
            }

            // 账户变动事件
            /*$data = ['wallet' => $walletLog, 'type' => $type];
            \think\Hook::listen('user_wallet_change', $data);*/
        } catch (HttpResponseException $e) {
            $data = $e->getResponse()->getData();
            $message = $data ? ($data['msg'] ?? '') : $e->getMessage();
            error_stop($message);
        } catch (\Exception $e) {
            dump($e);die();
            error_stop('您提交的数据不正确');
        }
        return true;
    }

    /**
     * @name 变更会员货款
     * @param  int|object   $user       会员对象或会员ID
     * @param  string       $type       变更类型:money=余额,commission=佣金,score=积分
     * @param  float|string        $amount     变更数量
     * @param  array        $ext        扩展字段
     * @param  string       $memo       备注
     * @return boolean
     */
    public static function changePayment($user, $type="payment_goods", $amount, $event="payment_goods_add", $ext = [], $memo = '',$flow_id=0)
    {
        // 判断用户
        if (is_numeric($user)) {
            $user = UserModel::find($user);
        }
        /*if (!$user) {
            error_stop('未找到用户');
        }*/
        // 判断金额
        /*if ($amount == 0) {
            error_stop('请输入正确的金额');
        }*/
        if($user){
            $before = $user[$type];
            $after = bcadd((string)$user[$type], (string)$amount, 2);
            try {
                // 更新会员余额信息
                $user->setInc($type, $amount);
                $user->setInc("payment_goods_all", $amount);
                // 获取操作人
                $oper = Operator::get($user);
                // 写入日志
                $walletLog = WalletLog::create([
                    'user_id' => $user["id"],
                    'amount' => $amount,
                    'type' => $type,
                    'before' => $before,
                    'after' => $after,
                    'event' => $event,
                    'memo' => $memo,
                    'ext' => $ext,
                    'oper_type' => $oper['type'],
                    'oper_id' => $oper['id'],
                    'order_id' => $ext['order_id']??0,
                    'flow_id' => $flow_id??0,//流向用户id
                ]);
                //money_payment=充值货款,money_payment_cost=充值货款成本价,
                //money_payment_income=充值货款收益,money_payment_cut_income=充值货款收益支出平级奖,
                //money_payment_cut_payment=充值货款收益支出充值货款
                // 钱包和积分记录存到 fastadmin 钱包积分记录表
                if (in_array($type, ['payment_goods','money_payment', 'money_payment_cost','money_payment_income','money_payment_cut_income','money_payment_cut_payment'])) {
                    $eventMap = (new WalletLog)->getEventMap();
                    $memo = $memo ?$memo: ($eventMap[$type][$event] ?? '');
                    $type_data=1;
                    if(in_array($type, ['money_payment_income','money_payment_cut_income','money_payment_cut_payment'])){
                        $type_data=2;
                    }
                    if ($type === 'money_payment_cut_payment' || $type=="payment_goods") {
                        //货款
                        PaymentMoneyLog::create(['user_id' => $user["id"], 'money' => $amount, 'before' => $before, 'after' => $after, 'memo' => $memo,"order_id"=>$ext["order_id"]??0,"order_sn"=>$ext["order_sn"]??'']);
                    } else{
                        MoneyLog::create(['user_id' => $user["id"], 'money' => $amount, 'before' => $before, 'after' => $after, 'memo' => $memo,"order_id"=>$ext["order_id"]??0,"type"=>$type_data]);
                    }
                }
                // 账户变动事件
                /* $data = ['wallet' => $wallet, 'type' => $type];
                 \think\Hook::listen('user_wallet_change', $data);*/
            } catch (HttpResponseException $e) {
                $data = $e->getResponse()->getData();
                $message = $data ? ($data['msg'] ?? '') : $e->getMessage();
                error_stop($message);
            } catch (\Exception $e) {
                error_stop('您提交的数据不正确');
            }
            return true;
        }
    }


    /**
     * 查找出货上级
     * */
    public static function checkAellAgent($user_id,$level=0)
    {
        $data=[];
        $user=User::with(['agent' => function ($query) {
            return $query->with('level_info');
        }])
            ->where(["id"=>$user_id])->find();//查找下单用户
        if(!empty($user["parent_user_id"])){
            $parent_user=User::with(['agent' => function ($query) {
                return $query->with('level_info');
            }])
                ->where(["id"=>$user["parent_user_id"]])->find();//查找下单用户上级
            if(!empty($parent_user)){
                // 扣除上级货款
                $parent_level=$parent_user["agent"]["level_info"]["level"]??0;
                $user_level=$user["agent"]["level_info"]["level"]??0;
                if(!empty($parent_level) && $parent_level>=2){
                    if($level>2){
                        $user_level=$level;
                    }
                    if($parent_level>$user_level){
                        //上级等级高于下单用户等级
                        $data=$parent_user;
                    }else{
                        return self::checkAellAgent($parent_user["id"],$user_level);
                    }
                }else{
                    return self::checkAellAgent($parent_user["id"],$user_level);
                }

            }
        }
        return $data;
    }


    /**
     * 平台自动进/出货
     * */
    /*public static function autorechargePayment($user){
        $user = UserModel::with(['agent' => function ($query) {
            return $query->with('level_info');
        }])
            ->where(["id"=>$user])->find();//查找用户
        if(!empty($user)){
            if($user["payment_goods"]<0){
                dump($user["id"]."--".$user["payment_goods"]??0);
                $payment_goods=abs($user["payment_goods"]);
                $level=$user["agent"]["level_info"]["commission_rules"];
                $money=bcmul($payment_goods,($level["commission_1"]/100),2);
                $data=[
                    "user_id"=>$user["id"],
                    "money"=>$money,//进/出货扣除金额
                    "payment_goods"=>$payment_goods,//进/出货货款
                    "order_sn"=>get_sn($user["id"]),
                    "order_amount"=>$money,//进/出货扣除金额
                ];
                dump($data);
                $model=new RechargeCorrectLog();
                $model->save($data);
                $model=$model->toArray();
                $parent_user_id=self::rechargePayment(["id"=>$user["id"]],$payment_goods,$model,1,$money);
                $id=self::checkAellAgent($user["id"]);//出货上级
                // 扣除用户余额
                self::change($user, 'money', -$model["money"], 'money_payment', [
                    'order_id' => $model["id"],
                    'order_sn' => $model["order_sn"],
                    'order_type' => "money_payment",
                ],'平台自动进/出货',$id??0);
                dump($parent_user_id."上");
                if(!empty($parent_user)){
                    $agent=UserModel::get($parent_user);
                    if(!empty($agent) && $agent["payment_goods"]<0){
                        self::autorechargePayment($agent["id"]);
                    }
                }
            }
            if(!empty($user["parent_user_id"])){
                self::autorechargePayment($user["parent_user_id"]);
            }
        }
    }*/
    /**
     * 平台自动进/出货
     * */
    public static function autorechargePayment($user){
        $user = UserModel::with(['agent' => function ($query) {
            return $query->with('level_info');
        }])
            ->where(["id"=>$user])->find();//查找用户
        if(!empty($user)){
            if($user["payment_goods"]<0){
                dump($user["id"]."--".$user["payment_goods"]??0);
                $payment_goods=abs($user["payment_goods"]);
                $level=$user["agent"]["level_info"]["commission_rules"];
                $money=bcmul($payment_goods,($level["commission_1"]/100),2);
                $data=[
                    "user_id"=>$user["id"],
                    "money"=>$money,//进/出货扣除金额
                    "payment_goods"=>$payment_goods,//进/出货货款
                    "order_sn"=>get_sn($user["id"]),
                    "order_amount"=>$money,//进/出货扣除金额
                ];
                dump($data);
                $model=new RechargeCorrectLog();
                $model->save($data);
                $model=$model->toArray();
                $parent_user_id=self::rechargePayment(["id"=>$user["id"]],$payment_goods,$model,1,$money);
                $id=self::checkAellAgent($user["id"]);//出货上级
                // 扣除用户余额
                self::change($user, 'money', -$model["money"], 'money_payment', [
                    'order_id' => $model["id"],
                    'order_sn' => $model["order_sn"],
                    'order_type' => "money_payment",
                ],'平台自动进/出货',$id["id"]??0);
                if(empty($id)){
                    //没有出货上级
                    Pclog::create([
                        "order_id"=>$model["id"],
                        "money"=>$model["money"],
                        "type"=>1,
                        "pv_price"=>$payment_goods,
                        "ext"=>[
                            'order_id' => $model["id"],
                            'order_sn' => $model["order_sn"],
                            'order_type' => "money_payment",
                            'memo' => "平台自动进/出货",
                        ],
                        "user_id"=>$user["id"],
                        "createtime"=>time(),
                    ]);
                }
                dump($parent_user_id."上");
                /*if(!empty($parent_user)){
                    $agent=UserModel::get($parent_user);
                    if(!empty($agent) && $agent["payment_goods"]<0){
                        self::autorechargePayment($agent["id"]);
                    }
                }*/
            }
            /*if(!empty($user["parent_user_id"])){
                self::autorechargePayment($user["parent_user_id"]);
            }*/
        }
    }
    /**
     * 进/出货
     * */
    public static function rechargePayment($user,$money,$order,$type=0,$cut_money=0)
    {
        $momo="充值货款";
        if($type==1){
            $momo="平台自动进/出货";
        }else{
            if($order->type =='recharge_due') $momo="进/出货";
        }
        $user=User::with(['agent' => function ($query) {
            return $query->with('level_info');
        }])
            ->where(["id"=>$user["id"]])->find();//查找下单用户
        $parent_user=[];
        if(!empty($user["parent_user_id"])){
            $parent_user=self::checkAellAgent($user["id"]);//出货上级
        }
        self::changePayment($user, 'payment_goods', $money, 'payment_goods_add', [
            'order_id' => $order["id"],
            'order_sn' => $order["order_sn"],
            'order_type' => 'payment_goods',
        ],$momo,$parent_user["id"]??0);
        if(!empty($user["parent_user_id"])){
            //用户上级不为空
            if(!empty($parent_user)){
                $parent_user=User::with(['agent' => function ($query) {
                    return $query->with('level_info');
                }])
                    ->where(["id"=>$parent_user["id"]])->find();//查找下单用户上级
                //dump($parent_user);die();
                $rate=$parent_user["agent"]["level_info"]["commission_rules"]["commission_1"]??40;//上级实际增加成本
                $parent_money=(bcmul($money,($rate/100),2));//上级余额成本
                //出货上级扣除货款
                self::changePayment($parent_user["id"], 'payment_goods',-$money, 'payment_goods_cut', [
                    'order_id' => $order["id"],
                    'order_sn' => $order["order_sn"],
                    'order_type' => "payment_goods_cut",
                ],'来自'.$user["nickname"].'['.$user["agent"]["level_info"]['name'].']'.$momo,$user["id"]);
                //增加余额成本
                //money_payment=充值货款,money_payment_cost=充值货款成本价,money_payment_income=充值货款收益,
                //money_payment_cut_income=充值货款收益支出平级奖,money_payment_cut_payment=充值货款收益支出充值货款
                self::changePayment($parent_user["id"], 'money',$parent_money, 'money_payment_cost', [
                    'order_id' => $order["id"],
                    'order_sn' => $order["order_sn"],
                    'order_type' => "money_payment_cost",
                ],'来自'.$user["nickname"].'['.$user["agent"]["level_info"]['name'].']'.$momo."成本",$user["id"]);
                //增加余额收益
                $commiss=bcsub($order["order_amount"],$parent_money,2);//收益
                self::changePayment($parent_user["id"], 'money',$commiss, 'money_payment_income', [
                    'order_id' => $order["id"],
                    'order_sn' => $order["order_sn"],
                    'order_type' => "money_payment_income",
                ],'来自'.$user["nickname"].'['.$user["agent"]["level_info"]['name'].']'.$momo."收益",$user["id"]);
                $pj_money=0;
                if($parent_user["id"]!=$user["parent_user_id"]){
                    //如果出货上级不是推荐上级
                    $pj_money=bcmul($commiss,0.2,2);//平级奖励

                    //给推荐上级加平级奖励

                    //2024--1-10  修改前-进货人上级拿平级奖   修改后-进货人上级关系链中等级和进货人一致的用户拿平级奖
                    $sideways=self::findSideways($user["parent_user_id"],$user["agent"]["level"],$parent_user);
                    if(!empty($sideways)){
                        //扣除出货上级平级奖励
                        self::changePayment($parent_user["id"], 'money',-$pj_money, 'money_payment_cut_income', [
                            'order_id' => $order["id"],
                            'order_sn' => $order["order_sn"],
                            'order_type' => "money_payment_cut_income",
                        ],"扣除平级奖励",$user["parent_user_id"]);
                        self::changePayment($sideways, 'money',$pj_money, 'money_payment_cut_income', [
                            'order_id' => $order["id"],
                            'order_sn' => $order["order_sn"],
                            'order_type' => "money_payment_cut_income",
                        ],"平级奖励",$parent_user["id"]);
                    }
                    /*self::changePayment($user["parent_user_id"], 'money',$pj_money, 'money_payment_cut_income', [
                        'order_id' => $order["id"],
                        'order_sn' => $order["order_sn"],
                        'order_type' => "money_payment_cut_income",
                    ],"平级奖励",$parent_user["id"]);*/


                    /*$pj_payment=bcmul($pj_money,0.05,2);//收益5%
                    self::changePayment($user["parent_user_id"], 'money',-$pj_payment, 'money_payment_cut_payment', [
                        'order_id' => $order["id"],
                        'order_sn' => $order["order_sn"],
                        'order_type' => "money_payment_cut_payment",
                    ],'扣除收益5%计入货款',$user["parent_user_id"]);
                    //扣除收益5%充值到货款
                    $parent=User::with(['agent' => function ($query) {
                        return $query->with('level_info');
                    }])
                        ->where(["id"=>$user["parent_user_id"]])->find();//查找下单用户上级
                    $parent_rate=$parent["agent"]["level_info"]["commission_rules"]["commission_1"]??40;//上级实际增加成本
                    $cut_payment_goods=bcdiv($pj_payment,($parent_rate/100),2);//货款
                    self::changePayment($user["parent_user_id"], 'payment_goods',$cut_payment_goods, 'money_payment_cut_payment', [
                        'order_id' => $order["id"],
                        'order_sn' => $order["order_sn"],
                        'order_type' => "money_payment_cut_payment",
                    ],'扣除收益5%计入货款',$user["parent_user_id"]);*/
                }
                /*$commiss=bcsub($commiss,$pj_money,2);//收益-平级奖励
                $cut_payment=bcmul($commiss,0.05,2);//收益5%
                self::changePayment($parent_user["id"], 'money',-$cut_payment, 'money_payment_cut_payment', [
                    'order_id' => $order["id"],
                    'order_sn' => $order["order_sn"],
                    'order_type' => "money_payment_cut_payment",
                ],'扣除收益5%计入货款',$parent_user["id"]);
                //扣除收益5%充值到货款
                $cut_payment_goods=bcdiv($cut_payment,($rate/100),2);//货款
                self::changePayment($parent_user["id"], 'payment_goods',$cut_payment_goods, 'money_payment_cut_payment', [
                    'order_id' => $order["id"],
                    'order_sn' => $order["order_sn"],
                    'order_type' => "money_payment_cut_payment",
                ],'扣除收益5%计入货款',$parent_user["id"]);*/
            }else{
                //平台
                /*$pc_money=(bcmul($money,0.4,2));//平台成本
                $pc_commiss=bcsub($order["order_amount"],$pc_money,2);//收益*/
                $level=Level::order("level","desc")->limit(2)->select();
                $ratio=0;
                if(!empty($level)){
                    if(!empty($level[1]["commission_rules"]["commission_1"]) && !empty($level[0]["commission_rules"]["commission_1"])){
                        $ratio=bcsub($level[1]["commission_rules"]["commission_1"],$level[0]["commission_rules"]["commission_1"],2);
                    }
                }
                if($ratio>0){
                    //pv*(（倒数第二等级-最高等级）/100)*0.2
                    $pv_money=bcmul($money,($ratio/100),2);
                    $pj_money=bcmul($pv_money,0.2,2);//平级奖励
                    //给推荐上级加平级奖励
                    //2024--1-10  修改前-进货人上级拿平级奖   修改后-进货人上级关系链中等级和进货人一致的用户拿平级奖
                    $sideways=self::findSideways($user["parent_user_id"],$user["agent"]["level"],$parent_user);
                    if(!empty($sideways)){
                        self::changePayment($sideways, 'money',$pj_money, 'money_payment_cut_income', [
                            'order_id' => $order["id"],
                            'order_sn' => $order["order_sn"],
                            'order_type' => "money_payment_cut_income",
                        ],"平级奖励");

                        //记录平台支出
                        Pclog::create([
                            "order_id"=>$order["id"],
                            "money"=>-$pj_money,
                            "type"=>2,
                            "pv_price"=>$money,
                            "ext"=>[
                                'order_id' => $order["id"],
                                'order_sn' => $order["order_sn"],
                                'order_type' => "money_payment_cut_income",
                                'ratio' => $ratio,
                                'pv_money' => $pv_money,
                                'money' => $money,
                                'memo' => "充正",
                            ],
                            "user_id"=>$sideways,
                            "createtime"=>time(),
                        ]);
                    }
                    /*self::changePayment($user["parent_user_id"], 'money',$pj_money, 'money_payment_cut_income', [
                        'order_id' => $order["id"],
                        'order_sn' => $order["order_sn"],
                        'order_type' => "money_payment_cut_income",
                    ],"平级奖励");*/
                }
                /*$pj_payment=bcmul($pj_money,0.05,2);//收益5%
                self::changePayment($user["parent_user_id"], 'money',-$pj_payment, 'money_payment_cut_payment', [
                    'order_id' => $order["id"],
                    'order_sn' => $order["order_sn"],
                    'order_type' => "money_payment_cut_payment",
                ],'扣除收益5%计入货款');
                //扣除收益5%充值到货款
                $parent=User::with(['agent' => function ($query) {
                    return $query->with('level_info');
                }])
                    ->where(["id"=>$user["parent_user_id"]])->find();//查找下单用户上级
                $parent_rate=$parent["agent"]["level_info"]["commission_rules"]["commission_1"]??40;//上级实际增加成本
                $cut_payment_goods=bcdiv($pj_payment,($parent_rate/100),2);//货款
                self::changePayment($user["parent_user_id"], 'payment_goods',$cut_payment_goods, 'money_payment_cut_payment', [
                    'order_id' => $order["id"],
                    'order_sn' => $order["order_sn"],
                    'order_type' => "money_payment_cut_payment",
                ],'扣除收益5%计入货款');*/
            }
        }
        return $user["parent_user_id"]??0;
    }

    /**
     * 查找进货 上级--关系链中等级和进货人一致的用户
     * */
    public static function findSideways($user_id,$level,$parent_user)
    {
        $user=UserModel::with(['agent'])
            ->where(["id"=>$user_id])->find();
        if(!empty($user)){
            if($level!=8){
                $parent_user=@$parent_user["id"]??0;
                if(empty($parent_user)) return 0;
            }
            if($user["agent"]["level"]==$level){
                return $user["id"];
            }else{
                if($level!=8 && (empty($parent_user) || $user_id==@$parent_user["id"])){
                    return 0;
                }
                return self::findSideways($user["parent_user_id"],$level,$parent_user);
            }
        }else{
            return 0;
        }
    }
    /**
     * 变更个体户余额
     * */
    public static function changeIndividuality($user, $amount, $ext = [], $memo = '',$type=0)
    {
        // 判断用户
        if (is_numeric($user)) {
            $user = Individuality::getById($user);
        }
        if (!$user) {
            dump('未找到个体户');
            //error_stop('未找到用户');
        }
        // 判断金额
        if ($amount == 0) {
            dump('请输入正确的金额');
            //error_stop('请输入正确的金额');
        }

        $before = $user->money;
        $after = bcadd((string)$user->money, (string)$amount, 2);
        try {
            // 更新会员余额信息
            $user->setInc('money', $amount);
            if($type==0){
                $user->setInc("all_money", $amount);
            }
            // 写入日志
            $walletLog = \app\admin\model\individuality\MoneyLog::create([
                'user_id' => $user->id,
                'amount' => $amount,
                'before' => $before,
                'after' => $after,
                'memo' => $memo,
                'ext' => json_encode($ext),
                'order_id' => $ext['order_id']??0,
            ]);
        } catch (HttpResponseException $e) {
            $data = $e->getResponse()->getData();
            $message = $data ? ($data['msg'] ?? '') : $e->getMessage();
            error_stop($message);
        } catch (\Exception $e) {
            error_stop('您提交的数据不正确');
        }
        return true;
    }
}
